

package cn.shengchao.controler.course;

import cn.dev33.satoken.annotation.SaIgnore;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.StrUtil;
import cn.shengchao.examstar.distribute.infrastrure.po.DistributeNodeInfo;
import cn.shengchao.examstar.distribute.infrastrure.service.DistributeNodeInfoService;
import cn.shengchao.examstar.pay.model.aggregate.CreateOrderAggregate;
import cn.shengchao.examstar.pay.model.service.IOrderService;
import cn.shengchao.examstar.product.domain.entity.FreeCourseKnowledgeProduct;
import cn.shengchao.examstar.product.ohs.local.message.ProductDto;
import cn.shengchao.examstar.rpc.distribute.enums.DistributeSaleRoleEnum;
import cn.shengchao.examstar.rpc.product.base.ContentProductTypeDefine;
import cn.shengchao.util.helper.LoginHelper;
import cn.shengchao.examstar.me.course.acl.ports.clients.IProductClient;
import cn.shengchao.examstar.me.course.domain.MyCourse;
import cn.shengchao.examstar.me.course.ohs.local.appervices.MyCourseAppService;
import cn.shengchao.examstar.me.course.ohs.local.messages.Learning;
import cn.shengchao.examstar.product.acl.adapters.repositories.NodeKnowledgePointRepository;
import cn.shengchao.examstar.product.infrastructure.dao.po.NodeKnowledgePoint;
import cn.shengchao.examstar.product.ohs.local.message.KnowledgeNodeDto;
import io.swagger.v3.oas.annotations.Operation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import top.continew.starter.web.model.R;

import java.util.*;
import java.util.stream.Collectors;

@RestController
@Slf4j
@CrossOrigin("${project.cross-origin}")
@RequestMapping("/api/${project.version}/myCourse")
public class MyCourseController {

    @Autowired
    private MyCourseAppService myCourseAppService;

    @Autowired
    private DistributeNodeInfoService distributeNodeInfoService;

    @Autowired
    private IProductClient iProductClient;

    @Autowired
    private NodeKnowledgePointRepository nodeKnowledgePointRepository;

    @Autowired
    IOrderService iOrderService;

    @GetMapping("ids")
    public List<Long> list() {
        Long uid = LoginHelper.getUserId();
        DistributeNodeInfo distributeNodeInfo = getDistributeNodeInfo(uid);
        if (distributeNodeInfo == null) {
            return myCourseAppService.getList(uid);
        } else {
            return myCourseAppService.getListByPlay(uid);
        }
    }

    @GetMapping("lastPlay")
    @Operation(summary = "最近播放", description = "最近播放")
    public KnowledgeNodeDto lastPlay(@RequestParam(required = false) String courseId) {
        Long uid = LoginHelper.getUserId();
        MyCourse userCourse = myCourseAppService.lastPlay(uid, courseId);
        if (userCourse == null) {
            return null;
        }
        KnowledgeNodeDto knowledgeNodeDto = iProductClient.getKnowledgeNodeDto(userCourse.getKnowledgeNodeId());
        knowledgeNodeDto.setUnlock(true);
        convertVideoFormat(knowledgeNodeDto);

        if (userCourse.getPlayProgress() != null) {
            knowledgeNodeDto.setProgress(Long.valueOf(userCourse.getPlayProgress()));
        } else {
            knowledgeNodeDto.setProgress(0L);
        }
        knowledgeNodeDto.setWatchProgress(userCourse.getWatchProgress());
        return knowledgeNodeDto;
    }

    @SaIgnore
    @GetMapping("{courseId}/knowledgeNode")
    @Operation(summary = "知识点", description = "知识点")
    public List<KnowledgeNodeDto> getKnowledgeList(@PathVariable Long courseId, String searchName) {
        boolean k12 = iProductClient.isK12(courseId);
        List<KnowledgeNodeDto> knowledgeList = iProductClient.getKnowledgeListByNewOrder(courseId, searchName, true);
        log.info("获取我的课程知识点:id:{},courseId:{}", StpUtil.isLogin() ? LoginHelper.getUserId() : "-1", courseId);

        // 获取用户的课程记录和分销身份
        List<MyCourse> myCourseDto = new ArrayList<>();
        DistributeNodeInfo distributeNodeInfo = null;

        if (StpUtil.isLogin()) {
            myCourseDto = myCourseAppService.getMyCourseKnowledgeList(LoginHelper.getUserId(), courseId);
            distributeNodeInfo = getDistributeNodeInfo(LoginHelper.getUserId());
        }

        // 知识点分组
        Map<Long, Optional<MyCourse>> courseMap = myCourseDto.stream()
                .collect(Collectors.groupingBy(MyCourse::getKnowledgeNodeId, Collectors.reducing((a, b) -> b)));

        // 处理每个知识点
        return processKnowledgeNodes(knowledgeList, k12, courseMap, distributeNodeInfo);
    }

    @GetMapping("knowledgePoint/{knowledgePointId}/relatedCourseNodes")
    @Operation(summary = "相关课节", description = "查询知识点下相关的课节")
    public List<KnowledgeNodeDto> getRelatedCourseNodesByKnowledgePoint(@PathVariable Long knowledgePointId) {
        log.info("获取知识点相关课节:id:{},knowledgePointId:{}", StpUtil.isLogin() ? LoginHelper.getUserId() : "-1", knowledgePointId);

        // 1. 查询与知识点关联的课程节点ID
        List<NodeKnowledgePoint> nodeKnowledgePoints = nodeKnowledgePointRepository.getNodeKnowledgePointByKnowledgePointId(knowledgePointId);

        if (nodeKnowledgePoints.isEmpty()) {
            return Collections.emptyList();
        }

        // 2. 获取所有的课程节点ID
        List<Long> courseNodeIds = nodeKnowledgePoints.stream()
                .map(NodeKnowledgePoint::getCourseNodeId)
                .toList();
        // 4. 查询所有课程节点详情并过滤有播放地址的课节
        List<KnowledgeNodeDto> courseNodes = fetchAndFilterCourseNodes(courseNodeIds);
        if (courseNodes.isEmpty()) {
            return Collections.emptyList();
        }

        // 5. 处理节点解锁状态
        return processNodeUnlockStatus(courseNodes, courseNodeIds);
    }

    @GetMapping
    public List<Learning> learning(@RequestParam String ids, @RequestParam String searchName) {
        Long uid = LoginHelper.getUserId();
        List<Learning> learning = myCourseAppService.learning(uid, ids.split(","));
        if (StrUtil.isEmpty(searchName)) {
            return learning;
        }
        return learning.stream().filter(item -> item.getCourseName().contains(searchName)).toList();
    }

    @GetMapping("{id}/freeUnlockSum")
    public R getFreeUnlockSum(@PathVariable Long id) {
        return R.ok(Map.of("freeUnlockSum", myCourseAppService.getFreeUnlockSum(id, LoginHelper.getUserId())));
    }

    @GetMapping("{id}/useFreeUnlockSum")
    public R useFreeUnlockSum(@PathVariable Long id, @RequestParam Long nodeId) {
        Long userId = LoginHelper.getUserId();
        FreeCourseKnowledgeProduct freeCourseKnowledgeProduct = iOrderService.loadFreeProduct(nodeId);
        if (freeCourseKnowledgeProduct == null) {
            return R.fail(R.fail().getCode(), "课程资源下线未找到");
        }
        if (ContentProductTypeDefine.COURSE_GK.name().equals(freeCourseKnowledgeProduct.getProductType()) && freeCourseKnowledgeProduct.getDiscountPrice() != null && freeCourseKnowledgeProduct.getDiscountPrice().doubleValue() > 0) {
            return R.fail(R.fail().getCode(), "本类课程不能免费解锁");
        }
        String orderId = CreateOrderAggregate.buildOrderNewId();
        myCourseAppService.useFreeUnlockSum(id, nodeId, userId, orderId);
        iOrderService.createFreeLockOrder(userId, orderId, freeCourseKnowledgeProduct.getCourseId(), freeCourseKnowledgeProduct.getCourseKnowledgeId());
        iOrderService.changeOrderPaySuccess(orderId);
        return R.ok();
    }

    /**
     * 获取用户分销身份信息
     */
    private DistributeNodeInfo getDistributeNodeInfo(Long userId) {
        return distributeNodeInfoService.getDistributeNodeInfoInCode(
                userId,
                List.of(DistributeSaleRoleEnum.ROLE_MKMG, DistributeSaleRoleEnum.ROLE_DSPD, DistributeSaleRoleEnum.ROLE_SLMB)
        );
    }

    /**
     * 查询并过滤课程节点
     */
    private List<KnowledgeNodeDto> fetchAndFilterCourseNodes(List<Long> courseNodeIds) {
        List<KnowledgeNodeDto> result = new ArrayList<>();
        for (Long courseNodeId : courseNodeIds) {
            KnowledgeNodeDto knowledgeNodeDto = iProductClient.getKnowledgeNodeDto(courseNodeId);
            if (knowledgeNodeDto == null) {
                continue;
            }
            try {
                ProductDto productDto = iProductClient.getProduct(knowledgeNodeDto.getCourseId());
                if (productDto != null && knowledgeNodeDto.getPlayUrl() != null) {
                    knowledgeNodeDto.setCover(productDto.getImageUrl());
                    boolean isk12 = iProductClient.isK12(knowledgeNodeDto.getCourseId());
                    knowledgeNodeDto.setCourseType(isk12 ? 1 : 0);
                    result.add(knowledgeNodeDto);
                }
            } catch (Exception e) {
                log.error("获取课程节点信息失败", e);
            }
        }
        return result;
    }

    /**
     * 处理节点解锁状态
     */
    private List<KnowledgeNodeDto> processNodeUnlockStatus(List<KnowledgeNodeDto> courseNodes, List<Long> courseNodeIds) {
        // 获取分销身份和已解锁节点信息
        DistributeNodeInfo distributeNodeInfo = null;
        Set<Long> unlockedNodeIds = Collections.emptySet();
        // 获取用户的课程记录和分销身份
        List<MyCourse> myCourseDto = new ArrayList<>();
        if (StpUtil.isLogin()) {
            // 检查用户分销身份
            Long userId = LoginHelper.getUserId();
            distributeNodeInfo = getDistributeNodeInfo(userId);

            // 从应用服务层获取用户已解锁课程节点信息
            myCourseDto = myCourseAppService.checkUserUnlockedCourseNodes(userId, courseNodeIds);
            unlockedNodeIds=myCourseDto.stream().map(MyCourse::getKnowledgeNodeId).collect(Collectors.toSet());
        }
        // 知识点分组
        Map<Long, Optional<MyCourse>> courseMap = myCourseDto.stream()
                .collect(Collectors.groupingBy(MyCourse::getKnowledgeNodeId, Collectors.reducing((a, b) -> b)));

        // 处理每个节点
        final DistributeNodeInfo finalDistributeNodeInfo = distributeNodeInfo;
        final Set<Long> finalUnlockedNodeIds = unlockedNodeIds;

        return courseNodes.stream().peek(item -> {
            // 判断解锁状态
            boolean isUnlocked = checkNodeUnlockStatus(item, finalUnlockedNodeIds, finalDistributeNodeInfo);
            item.setUnlock(isUnlocked);

            // 处理视频格式和播放权限
            convertVideoFormat(item);
            // 设置播放进度
            if (courseMap.get(item.getId()) != null) {
                MyCourse myCourse = courseMap.get(item.getId()).orElse(new MyCourse());
                item.setProgress(Long.valueOf(myCourse.getPlayProgress()));
                item.setWatchProgress(myCourse.getWatchProgress());
            }
            if (!isUnlocked) {
                item.setPlayUrl("");
            }
        }).toList();
    }

    /**
     * 处理知识点列表
     */
    private List<KnowledgeNodeDto> processKnowledgeNodes(
            List<KnowledgeNodeDto> knowledgeList,
            boolean k12, Map<Long, Optional<MyCourse>> courseMap,
            DistributeNodeInfo distributeNodeInfo) {

        return knowledgeList.stream().peek(item -> {
            // 检查解锁状态
            item.setUnlock(checkUnlock(courseMap, k12, item, distributeNodeInfo));

            // 处理视频格式
            convertVideoFormat(item);

            // 设置播放进度
            if (courseMap.get(item.getId()) != null) {
                MyCourse myCourse = courseMap.get(item.getId()).orElse(new MyCourse());
                item.setProgress(Long.valueOf(myCourse.getPlayProgress()));
                item.setWatchProgress(myCourse.getWatchProgress());
            }

            // 未解锁则清空播放地址
            if (!item.isUnlock()) {
                item.setPlayUrl("");
            }
        }).toList();
    }

    /**
     * 检查节点解锁状态
     */
    private boolean checkNodeUnlockStatus(KnowledgeNodeDto node, Set<Long> unlockedNodeIds, DistributeNodeInfo distributeNodeInfo) {
        // 判断课节是否解锁 - 先检查用户是否已购买/解锁了该课节
        if (unlockedNodeIds.contains(node.getId())) {
            return true;
        }
        //k12必须解锁
        if (node.getCourseType()==1) {
            return false;
        }

        // 否则根据分销身份判断解锁状态
        return distributeNodeInfo != null &&
                (distributeNodeInfo.getValidEndTime() == null ||
                        distributeNodeInfo.getValidEndTime().after(new Date()));
    }

    /**
     * 转换视频格式 (mp4 -> m3u8)
     */
    private void convertVideoFormat(KnowledgeNodeDto knowledgeNodeDto) {
        if (knowledgeNodeDto.getPlayUrl() != null && knowledgeNodeDto.getPlayUrl().contains("star")) {
            knowledgeNodeDto.setPlayUrl(knowledgeNodeDto.getPlayUrl().replace("mp4", "m3u8"));
        }
    }

    private boolean checkUnlock(Map<Long, Optional<MyCourse>> map, boolean k12, KnowledgeNodeDto item, DistributeNodeInfo distributeNodeInfo) {
        //存在记录或者0元课程
        if (map.get(item.getId()) != null) {
            return true;
        }
        //k12必须解锁
        if (k12) {
            return false;
        }
        //没有身份不解锁
        if (distributeNodeInfo == null) {
            return false;
        }
        //或者加盟商，会员，市场经理
        //无到期时间
        if (distributeNodeInfo.getValidEndTime() == null) {
            return true;
        }
        // 无到期时间或未过期
        return distributeNodeInfo.getValidEndTime().after(new Date());
    }
}
